﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace TransportAbstractionLibrary.UDP
{
    sealed class UDPConnection : IProtocolLowerLayer
    {
        IProtocolUpperLayer upperLayer;
        UDPServer udpServer;
        Guid id = new Guid("BAFBD487-B924-4635-B26F-98306E26BCC1");
        bool suppressInitialization;
        IPEndPoint endPoint;

        internal IPEndPoint EndPoint
        {
            get
            {
                return endPoint;
            }
        }

        public void ConnectionClosed()
        {
            upperLayer.ConnectionClosed();
        }

        #region IProtocolLowerLayer Members

        public void Bind(IProtocolUpperLayer upperLayer)
        {
            if (this.upperLayer == null)
            {
                this.upperLayer = upperLayer;
                upperLayer.Bind(this);
            }
            else
            {
                throw new ArgumentException("Can only be run once!");
            }
        }

        public void Send(byte[] data)
        {
            udpServer.SendData(this, data);
        }

        public IProtocolUpperLayer UpperLayer
        {
            get { return this.upperLayer; }
        }

        #endregion

        #region IProtocolBase Members

        public bool SuppressInitialization
        {
            get { return suppressInitialization; }
            set { suppressInitialization = value; }
        }

        public Guid Id
        {
            get { return id; }
        }

        public void Initialize()
        {
            upperLayer.Initialize();
        }

        public LayerType LayerType
        {
            get { return LayerType.Integrity | LayerType.Transport | LayerType.Package; }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            udpServer.Disconnect(this);
        }

        #endregion

        internal void ReceiveData(byte[] data)
        {
            this.upperLayer.Receive(data);
        }

        internal UDPConnection(UDPServer udpServer, IPEndPoint endPoint)
        {
            this.udpServer = udpServer;
            this.endPoint = endPoint;
        }
    }
}
